package domain;
import domain.exceptions.*;
import domain.Game.direction;
import java.util.Iterator;
import java.util.Vector;
import presentation.Observer;
/**
 *
 * @author shaigi
 */

public abstract class Agent {
    
    private String     _name;
    private direction  _lastDirection;
    private Square     _square;
    private int        _score;
    private Vector<Observer> _observers = new Vector<Observer>();
    
    public Agent(String name, direction lastDirection) {
        this._name          = name;
        this._lastDirection = lastDirection;
        this._square        = null;
        this._score         = 0;
        this._observers     = new Vector<Observer>();
    }
    
    
    public String getName() {
        return _name;
    }

    public Square getSquare() {
        return _square;
    }

    public Game.direction getLastDirection() {
        return _lastDirection;
    }
    
    public void setLastDirection(direction lastDirection) {
        this._lastDirection = lastDirection;
    }
    
    public void move(direction d) throws CannotMoveThereException{
        
        Square tmp;
        try{
            tmp = _square.neighbour(d);
            tmp.placeAgent(this);
            System.out.println(this.toString() + " moved to " + _square);        //del
            this._square = tmp;
            this._lastDirection = d;
        } catch (CannotPlaceAgentHereException ex) {
            System.out.println(toString() + " didn't move to " + _square);          //del
            throw new CannotMoveThereException("Cannot move there man 1!");
        } catch (NoSuchSquareException e){
            System.out.println(this.toString() + " didn't move to " + _square);      //del
            throw new CannotMoveThereException("Cannot move there man 2!");
        } finally {
            System.out.println("### " + this.toString() + " Position after move: " + _square + " ###");      //del
        }
        
        // updating score:
        setScore(getScore() - Game.STEP_COST);
        
        updateGui(0);
    }

    public void takeFlag(Square square) throws TryingToRemoveNonExistingFlagException{
        //TODO update _board
        updateGui(1);
        setScore(getScore() + square.getCost());
        try{
            Game._board.removeFlag(square);
        } catch (TryingToRemoveNonExistingFlagException ex){
            throw new TryingToRemoveNonExistingFlagException();
        }
    }
    
    public void placeAgent(Square square) {
        setSquare(square);
        try {
            Game._board.placeAgent(this, square);
        } catch (CannotPlaceAgentHereException ex) {
            System.err.println(ex.getMessage());
        }
        int cell = square.getColumn() + 1 + ( square.getRow() * Game._board.getNumberOfColumns());
        updateGui(cell);
    }
    public abstract void die();
    
    public int getScore(){
        return this._score;
    }
    
    public abstract void play();
    
    public void setSquare(Square square) {
        this._square = square;
    }

    public void setScore(int score) {
        this._score = score;
    }
    
    public void subscribe(Observer observer){
        this._observers.addElement(observer);
    }

    private void updateGui(int status) {
        for (Iterator<Observer> it = _observers.iterator(); it.hasNext();) {
            Observer observer = it.next();
            observer.updateGui(this, status);
        }
    }
    
    public String toString(){
        return "Agent: "+getName();
    }
}
